package jfae.core.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Editable when applied on a read method mark the corresponding property as editable.
 * You can specify order and groups by this annotation
 * Given the above class definition
 * <div class="codeblock">
 * <pre>
 * public class BaseEntity {
 * 
 * 	private String stringProp;
 * 	private Integer integerProp;
 * 	
 * 	{@code @}Editable(order=1,groupNames={"firstGroup","secondGroup"})
 * 	public String getStringProp() {
 * 		return stringProp;
 * 	}
 * 
 * 	public void setStringProp(String stringProp) {
 * 		this.stringProp = stringProp;
 * 	}
 * 
 * 	{@code @}Editable(order=2,groupNames="secondGroup")
 * 	public Integer getIntegerProp() {
 * 		return integerProp;
 * 	}
 * 
 * 	public void setIntegerProp(Integer integerProp) {
 * 		this.integerProp = integerProp;
 * 	}
 * 
 * }
 * </pre>
 * </div>
 * the properties <code>stringProp</code> and  <code>integerProp</code> is both editables,
 * but <code>stringProp</code> is configured on both "firstGroup" and "secondGroup" whereas
 * <code>integerProp</code> is configured only on "secondGroup".
 * <br />
 * Maybe you want to use it in a web page rendering something like:
 * 
 * <div class="codeblock">
 * <fieldset><legend>firstGroup</legend>
 * <table border="0">
 * 	<tr><td style="text-align:right;">stringProp<td><td><input readonly="readonly" /></td></tr>
 * </table>
 * </fieldset>
 * </div>
 * or
 * <div class="codeblock">
 * <fieldset><legend>secondGroup</legend>
 * <table border="0">
 * 	<tr><td style="text-align:right;">stringProp<td><td><input readonly="readonly" /></td></tr>
 * 	<tr><td style="text-align:right;">integerProp<td><td><input readonly="readonly" /></td></tr>
 * </table>
 * </fieldset>
 * </div>
 * <br />
 * 
 * @author bobpuley
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Editable {

	/**
	 * Default value for {@link #groupNames()}
	 */
	public static final String NO_GROUP_SET = "no_group";
	
	/**
	 * Default value for {@link #order()}
	 */
	public static final int DEFAULT_ORDER = Integer.MAX_VALUE;
	
	/**
	 * Indicate the ordinal position of the property.
	 * Basically the order imposed by this property is respected,
	 * but if more then one field have the same order position
	 * the real order depends on {@link FieldsComparator} that is
	 * used to reorder the field list after parsing.
	 * @return the order number of property
	 * {@link Integer#MAX_VALUE}
	 */
	int order() default DEFAULT_ORDER;
	
	/**
	 * Specify the groups within the property may be appear.
	 * Be careful not to use two groups that share one or more 
	 * properties if you want use both groups in the same form.
	 * @return an array of String representing the groups.
	 */
	String[] groupNames() default {NO_GROUP_SET};
	
}
